package com.zmn.plat.business.impl.orderconfig.documentarycontent;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.string.InitialUtil;
import com.zmn.mcc.common.dto.dept.DeptDRO;
import com.zmn.mcc.dubbo.interfaces.dept.DeptListRemoteService;
import com.zmn.plat.business.interfaces.orderconfig.documentarycontent.DocumentaryContentBService;
import com.zmn.plat.dubbo.utils.DubboConsts;
import com.zmn.plat.manager.dictionary.ProductDict;
import com.zmn.plat.model.entity.orderconfig.documentarycontent.DocumentaryContent;
import com.zmn.plat.model.entity.orderconfig.documentarycontent.DocumentaryContentQuery;
import com.zmn.plat.model.entity.orderconfig.documentarycontent.DocumentaryDepartmentRelations;
import com.zmn.plat.model.entity.orderconfig.documentarycontent.DocumentaryDepartmentRelationsQuery;
import com.zmn.plat.model.vo.orderconfig.documentarycontent.DocumentaryContentSimpleVO;
import com.zmn.plat.model.vo.orderconfig.documentarycontent.DocumentaryContentVO;
import com.zmn.plat.model.vo.orderconfig.documentarycontent.DocumentaryDepartmentRelationsVO;
import com.zmn.plat.services.interfaces.orderconfig.documentarycontent.DocumentaryContentService;
import com.zmn.plat.services.interfaces.orderconfig.documentarycontent.DocumentaryDepartmentRelationsService;

/**
 * 类描述：订单配置-跟单内容DocumentaryContentBServiceImpl
 *
 * @author linfeng
 * @since 2019/10/22/13:54
 */
@Service
public class DocumentaryContentBServiceImpl implements DocumentaryContentBService {
    private Logger logger = LoggerFactory.getLogger(DocumentaryContentBServiceImpl.class);

    @Resource
    DocumentaryContentService documentaryContentService;

    @Resource
    DocumentaryDepartmentRelationsService documentaryDepartmentRelationsService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private DeptListRemoteService deptListRemoteService;

    @Override
    public DocumentaryContentVO findByKey(Integer id) {
        DocumentaryContent documentaryContent = documentaryContentService.findByKey(id);
        DocumentaryDepartmentRelationsQuery query = new DocumentaryDepartmentRelationsQuery();
        query.setDocumentaryContentId(id);
        List<DocumentaryDepartmentRelationsVO> documentaryDepartmentRelationsVOList = documentaryDepartmentRelationsService.listByQuery(query);
        if (CollectionUtil.isNotNullOrEmpty(documentaryDepartmentRelationsVOList)) {
            List<Integer> deptIds = documentaryDepartmentRelationsVOList.stream().map(e -> e.getDocumentaryDepartmentId()).collect(Collectors.toList());
            if (CollectionUtil.isNotNullOrEmpty(deptIds)) {
                ResponseDTO<List<DeptDRO>> deptDros = deptListRemoteService.listDeptByDeptIds(deptIds);
                if (deptDros.isSuccess()) {
                    Map<Integer, DeptDRO> deptDROMap = deptDros.getData().stream().collect(Collectors.toMap(item -> item.getDeptId(), item -> item, (p, u) -> p));
                    documentaryDepartmentRelationsVOList.forEach(e -> {
                        e.setDocumentaryDepartmentName(deptDROMap.get(e.getDocumentaryDepartmentId()) == null ? "" : deptDROMap.get(e.getDocumentaryDepartmentId()).getDeptName());
                    });
                }
            }
        }

        DocumentaryContentVO documentaryContentVO = new DocumentaryContentVO();
        if (documentaryContent != null) {
            BeanUtils.copyProperties(documentaryContent, documentaryContentVO);
        }

        if (documentaryDepartmentRelationsVOList != null && documentaryDepartmentRelationsVOList.size() > 0) {
            documentaryContentVO.setDepartmentRelationsVOS(documentaryDepartmentRelationsVOList);
        } else {
            documentaryContentVO.setDepartmentRelationsVOS(new ArrayList<>());
        }

        return documentaryContentVO;
    }

    @Override
    @SuppressWarnings("Duplicates")
    public List<DocumentaryContentVO> listPageByQuery(DocumentaryContentQuery query) {
        List<Integer> documentaryDepartmentIds = new ArrayList<>();

        // 查询部门的所有父级部门以及自身
        if (query.getDocumentaryDepartmentId() != null) {
            ResponseDTO<List<DeptDRO>> responseDTO = deptListRemoteService.listDeptByLevelAndStatus(null, GlobalConsts.YES);
            List<DeptDRO> allDepts = new ArrayList<>();
            if (responseDTO.isSuccess()) {
                allDepts = responseDTO.getData();
            }

            Map<Integer, DeptDRO> deptMap = allDepts.stream().collect(Collectors.toMap(item -> item.getDeptId(), item -> item, (p, u) -> p));
            List<DeptDRO> depts = listParentDeptTreeByDeptId(deptMap, query.getDocumentaryDepartmentId());
            for (DeptDRO deptDRO : depts) {
                if (deptDRO != null) {
                    documentaryDepartmentIds.add(deptDRO.getDeptId());
                }
            }

            query.setDocumentaryDepartmentIds(documentaryDepartmentIds);
        }

        List<DocumentaryContent> documentaryContentList = documentaryContentService.listPageByQuery(query);
        List<DocumentaryDepartmentRelationsVO> documentaryDepartmentRelationsList = documentaryDepartmentRelationsService.listAll();
        ResponseDTO<List<DeptDRO>> deptDros = deptListRemoteService.listDeptByLevelAndStatus(null, GlobalConsts.YES);
        if (deptDros.isSuccess()) {
            Map<Integer, DeptDRO> deptDROMap = deptDros.getData().stream().collect(Collectors.toMap(item -> item.getDeptId(), item -> item, (p, u) -> p));
            documentaryDepartmentRelationsList.forEach(e -> {
                e.setDocumentaryDepartmentName(deptDROMap.get(e.getDocumentaryDepartmentId()) == null ? "" : deptDROMap.get(e.getDocumentaryDepartmentId()).getDeptName());
            });
        }
        List<DocumentaryContentVO> list = new ArrayList<>();
        Map<Integer, List<DocumentaryDepartmentRelationsVO>> map =
            documentaryDepartmentRelationsList.stream().collect(Collectors.groupingBy(DocumentaryDepartmentRelationsVO::getDocumentaryContentId));
        for (DocumentaryContent documentaryContent : documentaryContentList) {
            DocumentaryContentVO documentaryContentVO = new DocumentaryContentVO();
            BeanUtils.copyProperties(documentaryContent, documentaryContentVO);
            documentaryContentVO.setBizTypeName(ProductDict.getPlatNameByPlates(documentaryContent.getBizType()));
            DeptDRO dept = deptListRemoteService.getDept(documentaryContent.getResponsibleDepartmentId()).getData();
            documentaryContentVO.setResponsibleDepartmentName(dept == null ? "" : dept.getDeptName());
            documentaryContentVO.setResponsibleDepartmentName("");
            if (map != null && map.get(documentaryContent.getId()) != null) {
                documentaryContentVO.setDepartmentRelationsVOS(map.get(documentaryContent.getId()));
            } else {
                documentaryContentVO.setDepartmentRelationsVOS(new ArrayList<>());
            }
            list.add(documentaryContentVO);
        }
        return list;
    }

    @Override
    @SuppressWarnings("Duplicates")
    public List<DocumentaryContentSimpleVO> listByQuery(DocumentaryContentQuery query) {
        List<Integer> documentaryDepartmentIds = new ArrayList<>();

        // 查询部门的所有父级部门以及自身
        if (query.getDocumentaryDepartmentId() != null) {
            ResponseDTO<List<DeptDRO>> responseDTO = deptListRemoteService.listDeptByLevelAndStatus(null, GlobalConsts.YES);
            List<DeptDRO> allDepts = new ArrayList<>();
            if (responseDTO.isSuccess()) {
                allDepts = responseDTO.getData();
            }

            Map<Integer, DeptDRO> deptMap = allDepts.stream().collect(Collectors.toMap(item -> item.getDeptId(), item -> item, (p, u) -> p));
            List<DeptDRO> depts = listParentDeptTreeByDeptId(deptMap, query.getDocumentaryDepartmentId());
            for (DeptDRO deptDRO : depts) {
                if (deptDRO != null) {
                    documentaryDepartmentIds.add(deptDRO.getDeptId());
                }
            }

            query.setDocumentaryDepartmentIds(documentaryDepartmentIds);
        }

        List<DocumentaryContent> documentaryContentList = documentaryContentService.listByQuery(query);
        List<DocumentaryDepartmentRelationsVO> documentaryDepartmentRelationsList = documentaryDepartmentRelationsService.listAll();
        ResponseDTO<List<DeptDRO>> deptDros = deptListRemoteService.listDeptByLevelAndStatus(null, GlobalConsts.YES);
        if (deptDros.isSuccess()) {
            Map<Integer, DeptDRO> deptDROMap = deptDros.getData().stream().collect(Collectors.toMap(item -> item.getDeptId(), item -> item, (p, u) -> p));
            documentaryDepartmentRelationsList.forEach(e -> {
                e.setDocumentaryDepartmentName(deptDROMap.get(e.getDocumentaryDepartmentId()) == null ? "" : deptDROMap.get(e.getDocumentaryDepartmentId()).getDeptName());
            });
        }
        List<DocumentaryContentVO> list = new ArrayList<>();
        Map<Integer, List<DocumentaryDepartmentRelationsVO>> map =
            documentaryDepartmentRelationsList.stream().collect(Collectors.groupingBy(DocumentaryDepartmentRelationsVO::getDocumentaryContentId));
        for (DocumentaryContent documentaryContent : documentaryContentList) {
            DocumentaryContentVO documentaryContentVO = new DocumentaryContentVO();
            BeanUtils.copyProperties(documentaryContent, documentaryContentVO);
            if (map != null && map.get(documentaryContent.getId()) != null) {
                documentaryContentVO.setDepartmentRelationsVOS(map.get(documentaryContent.getId()));
            } else {
                documentaryContentVO.setDepartmentRelationsVOS(new ArrayList<>());
            }
            list.add(documentaryContentVO);
        }

        List<DocumentaryContentSimpleVO> documentaryContentSimpleVOList = list.stream().map(documentaryContentVO -> {
            DocumentaryContentSimpleVO documentaryContentSimpleVO = new DocumentaryContentSimpleVO();
            BeanUtils.copyProperties(documentaryContentVO, documentaryContentSimpleVO);
            boolean flag = false;
            if (query.getDocumentaryDepartmentId() != null) {
                List<DocumentaryDepartmentRelationsVO> documentaryDepartmentRelationsVOList = documentaryContentVO.getDepartmentRelationsVOS();
                if (documentaryDepartmentRelationsVOList != null && documentaryDepartmentRelationsVOList.size() != 0) {
                    for (DocumentaryDepartmentRelationsVO documentaryDepartmentRelationsVO : documentaryDepartmentRelationsVOList) {
                        for (Integer deptId : documentaryDepartmentIds) {
                            if (deptId.intValue() == documentaryDepartmentRelationsVO.getDocumentaryDepartmentId().intValue()) {
                                documentaryContentSimpleVO.setDepartmentPriority(documentaryDepartmentRelationsVO.getPriority());
                                flag = true;
                                break;
                            }
                        }

                        if (flag) {
                            break;
                        }
                    }
                }
            }

            return documentaryContentSimpleVO;
        }).collect(Collectors.toList());

        return documentaryContentSimpleVOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("Duplicates")
    public Integer insert(DocumentaryContentVO documentaryContentVO) {
        DocumentaryContent documentaryContent = new DocumentaryContent();
        BeanUtils.copyProperties(documentaryContentVO, documentaryContent);
        if (documentaryContent.getSort() == null) {
            documentaryContent.setSort(1);
        }
        if (documentaryContentVO.getContent() != null && (!documentaryContentVO.getContent().equals(""))) {
            documentaryContent.setFirstLetter(InitialUtil.getFristEnName(documentaryContentVO.getContent()));
        }
        documentaryContentService.insert(documentaryContent);

        List<DocumentaryDepartmentRelationsVO> documentaryContentVOList = documentaryContentVO.getDepartmentRelationsVOS();
        List<DocumentaryDepartmentRelations> departmentRelationsList = new ArrayList<>();
        if (documentaryContentVOList != null && documentaryContentVOList.size() > 0) {
            for (DocumentaryDepartmentRelationsVO documentaryDepartmentRelationsVO : documentaryContentVOList) {
                DocumentaryDepartmentRelations documentaryDepartmentRelations = new DocumentaryDepartmentRelations();
                BeanUtils.copyProperties(documentaryDepartmentRelationsVO, documentaryDepartmentRelations);
                documentaryDepartmentRelations.setDocumentaryContentId(documentaryContent.getId());
                documentaryDepartmentRelations.setCreater(documentaryContentVO.getCreater());
                documentaryDepartmentRelations.setCreateTime(documentaryContentVO.getCreateTime());
                departmentRelationsList.add(documentaryDepartmentRelations);
            }
            documentaryDepartmentRelationsService.insertBatch(departmentRelationsList);
        }

        return documentaryContent.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("Duplicates")
    public void update(DocumentaryContentVO documentaryContentVO) {
        DocumentaryContent documentaryContent = new DocumentaryContent();
        BeanUtils.copyProperties(documentaryContentVO, documentaryContent);
        if (documentaryContent.getSort() == null) {
            documentaryContent.setSort(1);
        }
        if (documentaryContentVO.getContent() != null && (!documentaryContentVO.getContent().equals(""))) {
            documentaryContent.setFirstLetter(InitialUtil.getFristEnName(documentaryContentVO.getContent()));
        }
        documentaryContentService.updateByKey(documentaryContent);
        if (documentaryContentVO.getId() != null) {
            documentaryDepartmentRelationsService.deleteByDocumentaryContentId(documentaryContentVO.getId());
        }

        List<DocumentaryDepartmentRelationsVO> documentaryContentVOList = documentaryContentVO.getDepartmentRelationsVOS();
        List<DocumentaryDepartmentRelations> departmentRelationsList = new ArrayList<>();
        if (documentaryContentVOList != null && documentaryContentVOList.size() > 0) {
            for (DocumentaryDepartmentRelationsVO documentaryDepartmentRelationsVO : documentaryContentVOList) {
                DocumentaryDepartmentRelations documentaryDepartmentRelations = new DocumentaryDepartmentRelations();
                BeanUtils.copyProperties(documentaryDepartmentRelationsVO, documentaryDepartmentRelations);
                documentaryDepartmentRelations.setDocumentaryContentId(documentaryContent.getId());
                documentaryDepartmentRelations.setCreater(documentaryContentVO.getUpdater());
                documentaryDepartmentRelations.setCreateTime(documentaryContentVO.getUpdateTime());
                departmentRelationsList.add(documentaryDepartmentRelations);
            }
            documentaryDepartmentRelationsService.insertBatch(departmentRelationsList);
        }
    }

    private List<DeptDRO> listParentDeptTreeByDeptId(Map<Integer, DeptDRO> deptMap, Integer deptId) {
        List<DeptDRO> deptList = new ArrayList<>();
        return listParentDeptTreeByDeptId(deptMap, deptList, deptId);
    }

    private List<DeptDRO> listParentDeptTreeByDeptId(Map<Integer, DeptDRO> deptMap, List<DeptDRO> deptList, Integer deptId) {
        DeptDRO dept = deptMap.get(deptId);
        deptList.add(dept);
        if (dept == null || dept.getParentId() == null || Objects.equals(GlobalConsts.TOP_ID, dept.getParentId())) {
            return deptList;
        }
        return listParentDeptTreeByDeptId(deptMap, deptList, dept.getParentId());
    }
}
